package com.jt.common.util;

import java.io.UnsupportedEncodingException;
import java.lang.reflect.Field;
import java.text.NumberFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;
import java.util.Random;
import java.util.StringTokenizer;


public abstract class StringUtils extends org.springframework.util.StringUtils {

    /**
     * @Description : 去除首字符串
     * @return : String
     * @Creation Date : 2015-4-23 上午11:36:48
     * @Author : wangchao
     */

    public static String[] letterArray = {"A", "B", "C", "D", "E", "F", "G", "H", "J", "K", "L", "M", "N",
            "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z",
            "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "m", "n", "o",
            "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"};

    public static String removeFristStr(String str, String substr) {
        if (!hasText(str))
            return "";
        return str.substring(substr.length());
    }

    /**
     * @return : String
     * @Description : 去除末字符串
     * @Creation Date : 2016年5月21日 下午10:29:16
     * @Author : chichangchao
     */
    public static String removeEndStr(final String str, final String remove) {
        if (!hasText(str) || !hasText(remove)) {
            return "";
        }
        if (str.endsWith(remove)) {
            return str.substring(0, str.length() - remove.length());
        }
        return str;
    }

    /**
     * @return : String
     * @Description : 去除上级元素
     * @Creation Date : 2015-5-5 下午2:29:37
     * @Author : wangchao
     */
    public static String trimParent(String generateJson, String parent) {
        if (!hasText(generateJson))
            return "";
        StringBuilder resutl = new StringBuilder(generateJson.trim());
        resutl = resutl.deleteCharAt(0);
        resutl = resutl.deleteCharAt(resutl.length() - 1);
        return delete(resutl.toString(), "\"" + parent + "\":");
    }

    public static String generteBatchNum(String source, int length) {
        String value = String.valueOf(source);
        while (value.length() < length) {
            value = "0" + value;
        }
        return value;
    }

    /**
     * @return : String
     * @Description : 字符串快速连接方法
     * @Creation Date : 2016年5月6日 上午11:30:04
     * @Author : wangchao
     */
    public static String append(String... values) {
        if (values == null || values.length == 0)
            return "";
        StringBuilder builder = new StringBuilder();
        for (String val : values) {
            builder.append(val);
        }
        return builder.toString();
    }

    /**
     * 打印堆栈数量，超过这个数量会省略输出
     */
    public static final int PRINT_STACK_COUNT = 5;

    private static final String FORMAT_STRING = "yyyy-MM-dd HH:mm:ss";
    private static final ThreadLocal<SimpleDateFormat> format = new ThreadLocal<SimpleDateFormat>() {
        @Override
        protected synchronized SimpleDateFormat initialValue() {
            return new SimpleDateFormat(FORMAT_STRING);
        }

        ;
    };

    /**
     * 构造器
     */
    private StringUtils() {

    }

    /**
     * 判断输入字符串是否满足以下非空条件：<br>
     * 不为空，剪头去尾后长度大于0，不论大小写字符串都不等于null
     *
     * @param str 输入要判断的串
     * @return 根据依据判断出的布尔结果
     */
    public static final boolean isNullOrBlank(String str) {
        if (str == null) {
            return true;
        }
        if (str.length() <= 0) {
            return true;
        }
        return false;
    }

    /**
     * 转换为公里
     *
     * @param dise
     * @return
     */
    public static final String distanceToString(Double dise) {
        String distance = "";
        if (dise >= 1000) {
            distance = String.valueOf(dise / 1000).substring(0, String.valueOf(dise / 1000).indexOf(".") + 3) + "公里";

        } else if (dise > 0 && dise < 1000) {
            distance = String.valueOf(dise / 1000).substring(0, String.valueOf(dise / 1000).indexOf(".") + 3) + "公里";
        } else {
            distance = String.valueOf(dise) + "公里";
        }
        return distance;
    }


    /**
     * 非null而且内容不为空
     *
     * @param str
     * @return
     */
    public static final boolean notNullOrBlank(String str) {
        if (str == null) {
            return false;
        }
        if (str.length() <= 0) {
            return false;
        }
        return true;
    }

    /**
     * 安全的trim方式，剪头去尾，在输入为空的情况下也能安全剪除字符串两端的空白
     *
     * @param str
     * @return 返回绝不为空，至少为长度为0的串
     */
    public static final String trim(String str) {
        if (str == null) {
            return "";
        }
        return str.trim();
    }

    /**
     * 获得字符串的数组表示
     *
     * @param srcStr   使用(delim)符号分割的字符串
     * @param delim    分割符，如果符号不是打印符号，则使用空格替代
     * @param zeroSize 决定当拆不出任何数组的时候，是返回null还是零长度的对象，如果为true则返回0长度对象，否则直接null
     * @return
     */
    public static final String[] splitToArray(String srcStr, String delim,
                                              boolean zeroSize) {
        String[] strArray = null;
        if (!isNullOrBlank(srcStr)) {
            // 如果分割符不是特殊符号，则默认使用空格分割
            if (isNullOrBlank(delim)) {
                delim = " ";
            }
            StringTokenizer stringTokenizer = new StringTokenizer(srcStr, delim);
            strArray = new String[stringTokenizer.countTokens()];
            for (int i = 0; stringTokenizer.hasMoreTokens(); i++) {
                strArray[i] = stringTokenizer.nextToken();
            }
        }
        if (zeroSize && strArray == null) {
            // 为了节省空间，需要指定长度为0
            strArray = new String[0];
        }
        return strArray;
    }

    /**
     * null convert to blank
     *
     * @param string
     * @return
     */
    public static final String null2blank(String string) {
        return string == null ? "" : string;
    }

    /**
     * 移除字符串的空格
     *
     * @param src
     * @return
     */
    public static final String removeSpace(String src) {
        if (src == null) {
            return "";
        }
        char[] ss = src.toCharArray();
        int j = 0;
        for (int i = 0; i < ss.length; i++) {
            if (ss[i] != ' ') {
                ss[j++] = ss[i];
            }
        }
        return new String(ss).substring(0, j);
    }

    /**
     * 将异常转换为堆栈输出串
     *
     * @param e 需要输出的异常对象
     * @return 转换出的字符串，不为空
     */
    public static final String toStacksString(Throwable e) {
        if (e == null) {
            return "";
        }
        StringBuffer eStrBuf = new StringBuffer("以下是异常（");
        eStrBuf.append(e.getClass().getName());
        eStrBuf.append(':');
        eStrBuf.append(e.getMessage());
        eStrBuf.append("）的堆栈信息：\r\n");
        StackTraceElement[] traces = e.getStackTrace();
        int tracesSize = traces.length;
        for (int i = 0; i < tracesSize; i++) {
            eStrBuf.append("\tat ");// 在堆栈行开始增加空格
            StackTraceElement trace = traces[i];
            eStrBuf.append(trace.toString());
            eStrBuf.append("\r\n");
        }
        ex(eStrBuf, e.getCause());
        return eStrBuf.toString();
    }

    /**
     * 将异常输出到字符缓冲中
     *
     * @param sb 需要输出到的目标字符串缓冲，不可为空
     * @param t  需要输出的异常
     * @return 如果还有引起异常的源，那么返回true
     */
    private final static boolean ex(StringBuffer sb, Throwable t) {
        if (t != null) {
            sb.append("Caused by: ");
            sb.append(t.getClass().getName());
            sb.append(": ");
            sb.append(t.getMessage());
            sb.append("\r\n");
            StackTraceElement[] traces = t.getStackTrace();
            int tracesSize = traces.length;
            for (int i = 0; i < tracesSize; i++) {
                if (i < PRINT_STACK_COUNT) {
                    sb.append("\tat ");// 在堆栈行开始增加空格
                    StackTraceElement trace = traces[i];
                    sb.append(trace.toString() + "\r\n");
                } else {
                    sb.append("\t... ");
                    sb.append(tracesSize - PRINT_STACK_COUNT);
                    sb.append(" more\r\n");
                    break;
                }
            }
            if (ex(sb, t.getCause())) {
                return true;
            }
        }
        return false;
    }

    /**
     * FIXME
     *
     * @param str
     * @param codec
     * @return
     */
    public static final String encode(String str, String codec) {
        try {
            return new String(str.getBytes("UTF-8"), codec);
        } catch (UnsupportedEncodingException e) {
            // e.printStackTrace();
            return null;
        }
    }

    /**
     * FIXME
     *
     * @param str
     * @param codec
     * @return
     */
    public static final String decode(String str, String codec) {
        try {
            return new String(str.getBytes(codec), "UTF-8");
        } catch (UnsupportedEncodingException e) {
            // e.printStackTrace();
            return null;
        }
    }

    /**
     * 两个字符串比较(去除空格)
     *
     * @param str1
     * @param str2
     * @return
     */
    public static final boolean compare(String str1, String str2) {

        if (trim(str1).equals(trim(str2))) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 两个字符串比较
     *
     * @param str1
     * @param str2
     * @return
     */
    public static final boolean compareComplete(String str1, String str2) {
        if (trimComplete(str1).equals(trimComplete(str2))) {
            return true;
        } else {
            return false;
        }
    }

    public static final String trimComplete(String str) {
        if (str == null) {
            return "";
        }
        return str;
    }


    public static final boolean isIn(String substring, String[] source) {

        if (source == null || source.length == 0) {
            return false;
        }
        for (int i = 0; i < source.length; i++) {
            String aSource = source[i];
            if (aSource.equals(substring)) {
                return true;
            }
        }
        return false;
    }


    /**
     * convertParams(转换为Map参数)
     *
     * @param source PO对象
     * @param params 参数Map void
     * @throws
     * @since 1.0.0
     */
    public static void convertParams(Object source, Map<String, Object> params) {
        if (source == null || params == null) {
            return;
        }
        convertParams(source, params, source.getClass(), false);
    }

    public static void convertNotEmptyParams(Object source, Map<String, Object> params) {
        if (source == null || params == null) {
            return;
        }
        convertParams(source, params, source.getClass(), true);
    }

    private static void convertParams(Object source, Map<String, Object> params, Class<?> c, boolean notEmpty) {
        Class<?> s = c.getSuperclass();
        if (s != null) {
            if (s.equals(Object.class) == false) {
                convertParams(source, params, s, notEmpty);
            }
        }
        for (Field field : c.getDeclaredFields()) {
            field.setAccessible(true);
            Object fieldval = null;
            try {
                fieldval = field.get(source);
            } catch (IllegalArgumentException e) {
            } catch (IllegalAccessException e) {
            }
            if (fieldval != null && "serialVersionUID".equals(field.getName()) == false && "this$0".equals(field.getName()) == false) {
                String tmp = String.valueOf(fieldval);
                if (notEmpty == false || !StringUtils.notNullOrBlank(tmp)) {
                    if (field.getGenericType().equals(Date.class)) {
                        params.put(field.getName(), format.get().format((Date) fieldval));
                    } else {
                        params.put(field.getName(), fieldval);
                    }
                }
            }
        }
    }

    /**
     * 生成长度为length 的验证码
     *
     * @param length
     * @return
     */
    public static String getVerificationCode(int codeLen) {

        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < codeLen; i++) {

            sb.append(new Random().nextInt(10));
        }
        return sb.toString();
    }

    /**
     * 生成长度为length都为 0 的字符串
     *
     * @param length
     * @return
     */
    public static String getJointStringByZero(int len) {

        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < len; i++) {

            sb.append("0");
        }
        return sb.toString();
    }

    /**
     * 获取len长度的随机字母字符串
     *
     * @param len
     * @return
     */
    public static String getLetterRandom(int len) {

        int length = letterArray.length;
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < len; i++) {

            int index = new Random().nextInt(length);
            sb.append(letterArray[index]);
        }
        return sb.toString();
    }

    /**
     * 验证参数不可为 null
     *
     * @param objs
     */
    public static void validateNotNull(Object... objs) {
        if (objs != null && objs.length > 0) {
            for (int i = 0; i < objs.length; i++) {
                if (objs[i] == null) {
                    throw new IllegalArgumentException("objs[" + i + "] is null.");
                }
            }
        }
    }

    /**
     * 验证字符串不可为空
     *
     * @param strs
     */
    public static void validateNotEmpty(String... strs) {
        if (strs != null && strs.length > 0) {
            for (int i = 0; i < strs.length; i++) {
                if (StringUtils.trimToNull(strs[i]) == null) {
                    throw new IllegalArgumentException("strs[" + i + "] is null or empty.");
                }
            }
        }
    }

    /**
     * 去掉前后空格
     *
     * @param string
     * @return
     */
    public static String trimToNull(String str) {
        final String ts = trim(str);
        return isEmpty(ts) ? null : ts;
    }


    /**
     * 去掉字符串最后一位
     *
     * @param string
     * @return
     */
    public static String removeLastChar(String str) {
        if (StringUtils.isEmpty(str)) {
            return "";
        }
        return str.substring(0, str.length() - 1);
    }

    /**
     * 验证数字是否大于0
     *
     * @param ds
     */
    public static void validateGreaterThanZero(Number... ds) {
        if (ds != null && ds.length > 0) {
            for (int i = 0; i < ds.length; i++) {
                if (ds[i] == null || ds[i].doubleValue() <= 0) {
                    throw new IllegalArgumentException("ds[" + i + "] is null or less then 0.");
                }
            }
        }
    }

    public static boolean isNoneBlank(String str) {
        if (isEmpty(str)) {
            return false;
        }
        return true;
    }

    public static boolean isBlank(String str) {
        return isEmpty(str);
    }

    /**
     * 手机号中间四位脱敏
     *
     * @param str
     * @return
     */
    public static String simConceal(String str) {
        return str.substring(0, str.length() - (str.substring(3)).length()) + "****" + str.substring(7);
    }

    /**
     * 数组转换字符串
     */
    public static String arrayToString(String[] arr) {
        if (arr == null || arr.length == 0) {
            return "";
        }
        StringBuffer st = new StringBuffer();
        for (String s : arr) {
            st.append(s).append(",");
        }
        return removeLastChar(st.toString());
    }

    /**
     * Double 转string 去除科学记数法显示
     *
     * @param d
     * @return
     */
    public static String double2Str(Double d) {
        if (d == null) {
            return "";
        }
        NumberFormat nf = NumberFormat.getInstance();
        nf.setGroupingUsed(false);
        return (nf.format(d));
    }

    /**
     * 获取二级状态码的二级状态
     *
     * @return
     */
    public static String carSubStatu2Str2(String carSubStatu) {
        if (carSubStatu.contains("-")) {
            int index = carSubStatu.indexOf("-");
            return carSubStatu.substring(index + 1, carSubStatu.length());
        }
        return "";
    }

    /**
     * 获取二级状态码的一级状态
     *
     * @return
     */
    public static String carSubStatu2Str1(String carSubStatu) {
        if (carSubStatu.contains("-")) {
            int index = carSubStatu.indexOf("-");
            return carSubStatu.substring(0, index);
        }
        return carSubStatu;
    }
}
